package v1ch05.reflection;

import java.lang.reflect.*;
import java.util.*;

/**
 * 打印类的所有构造函数，类方法和字段
 * 该程序使用反射来打印类的所有功能。
 *
 * @author Cay Horstmann
 * @version 1.1 2004-02-21
 */
public class ReflectionTest {
	public static void main(String[] args) {
		//从命令行参数或用户输入中读取类名
		String name = "";
		if (args.length > 0) {
			name = args[0];
		} else {
			Scanner in = new Scanner(System.in);
			System.out.println("Enter class name (e.g. java.util.Date): ");
			//name = in.next(); //必须要数据
			name = in.nextLine();//可以不要输入，回车也算
		}
		
		Class c = String.class;
		//Class c = new String().getClass();
		name = "".equals(name) ? c.getName() : name;
		printAllByClassPath(name);
		System.exit(0);
	}
	
	/**
	 * 打印类的所有构造函数，类方法和字段
	 *
	 * @param cl
	 */
	public static void printAllByClassPath(String classpath) {
		try {
			//打印类名和超类名（如果！= Object）
			Class cl = Class.forName(classpath);
			Class supercl = cl.getSuperclass();
			//修饰符
			String modifiers = Modifier.toString(cl.getModifiers());
			if (modifiers.length() > 0) {
				System.out.print(modifiers + " ");
			}
			System.out.print("class " + classpath);
			//如果有父类，打印父类名称
			if (supercl != null && supercl != Object.class) {
				System.out.print(" extends " + supercl.getName());
			}
			System.out.print("\n{\n");
			//打印构造器
			printConstructors(cl);
			System.out.println();
			//打印类方法
			printMethods(cl);
			System.out.println();
			//打印域字段
			printFields(cl);
			System.out.println("}");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 打印类的所有构造函数
	 *
	 * @param cl a class
	 */
	public static void printConstructors(Class cl) {
		Constructor[] constructors = cl.getDeclaredConstructors();
		
		for (Constructor c : constructors) {
			String name = c.getName();
			System.out.print("   ");
			//打印修饰符
			String modifiers = Modifier.toString(c.getModifiers());
			if (modifiers.length() > 0) {
				System.out.print(modifiers + " ");
			}
			System.out.print(name + "(");
			
			//打印参数类型
			Class[] paramTypes = c.getParameterTypes();
			for (int j = 0; j < paramTypes.length; j++) {
				if (j > 0) {
					System.out.print(", ");
				}
				System.out.print(paramTypes[j].getName());
			}
			System.out.println(");");
		}
	}
	
	/**
	 * 打印类的所有方法
	 *
	 * @param cl a class
	 */
	public static void printMethods(Class cl) {
		Method[] methods = cl.getDeclaredMethods();
		
		for (Method m : methods) {
			Class retType = m.getReturnType();
			String name = m.getName();
			
			System.out.print("   ");
			//打印修饰符，返回类型和方法名称
			String modifiers = Modifier.toString(m.getModifiers());
			if (modifiers.length() > 0) {
				System.out.print(modifiers + " ");
			}
			System.out.print(retType.getName() + " " + name + "(");
			
			//打印参数类型
			Class[] paramTypes = m.getParameterTypes();
			for (int j = 0; j < paramTypes.length; j++) {
				if (j > 0) {
					System.out.print(", ");
				}
				System.out.print(paramTypes[j].getName());
			}
			System.out.println(");");
		}
	}
	
	/**
	 * 打印类的所有字段
	 *
	 * @param cl a class
	 */
	public static void printFields(Class cl) {
		Field[] fields = cl.getDeclaredFields();
		
		for (Field f : fields) {
			Class type = f.getType();
			String name = f.getName();
			System.out.print("   ");
			//打印修饰符
			String modifiers = Modifier.toString(f.getModifiers());
			if (modifiers.length() > 0) {
				System.out.print(modifiers + " ");
			}
			System.out.println(type.getName() + " " + name + ";");
		}
	}
}
